/*
 * launcher.cpp
 *
 *  Created on: Oct 16, 2013
 *      Author: m
 */

#include <iostream>
#include <cstdlib>
#include "DefinicionesComunes.h"
#include "NewMessageQueue.h"
#include "NewSemaphore.h"
#include "NewSharedMemory.h"
#include "Sequence.h"
#include "CPrinter.h"
#include "ProcessAux.h"

#define ARG_CANT_VUELOS      1
#define ARG_CANT_PASAJEROS   2
#define ARG_CANT_ESTAC_VERIF 3

using namespace ipc;

int main( int argc, char* argv[] )
{
    int nVuelos;
    int nPasajeros;
    int nEstacionesVerificacion;

    CPrinter::setHeader( "launcher" );

    /*
     * Parseo los argumentos
     *
     * argv[1] Cantidad de vuelos
     * argv[2] Cantidad de pasajeros
     * argv[3] Cantidad de estaciones de Verificación
     */

    if ( argc != 4 )
    {
        CPrinter::printErr("ERROR: Cantidad de Argumentos Invalida.\n"
            "USO:\tlauncher [nVuelos] [nPasajeros] [nEstacionesVerificacion]");
        exit(1);
    }

    std::stringstream ss;

    ss.str( argv[ARG_CANT_VUELOS] );
    ss >> nVuelos;
    ss.clear();

    ss.str( argv[ARG_CANT_PASAJEROS] );
    ss >> nPasajeros;
    ss.clear();

    ss.str( argv[ARG_CANT_ESTAC_VERIF] );
    ss >> nEstacionesVerificacion;
    ss.clear();

    // Construyo e inicializo los IPCs:
    SharedMemory<int>::create( IPC_BASE_FILE, SHM_CONT_EQUIPAJE, nVuelos ).initialize( 0 );
    SharedMemory<int>::create( IPC_BASE_FILE, SHM_CONT_SOSPECHOSO, nVuelos ).initialize( 0 );
    Semaphore::create( IPC_BASE_FILE, MUTEX_CONT_EQUIPAJE, nVuelos ).initialize( 1 );
    Semaphore::create( IPC_BASE_FILE, MUTEX_CONT_SOSPECHOSO, nVuelos ).initialize( 1 );
    MessageQueue<MensajeEquipaje>::create( IPC_BASE_FILE, MQ_SIN_VERIF );
    MessageQueue<MensajeEquipaje>::create( IPC_BASE_FILE, MQ_SOSPECHOSO );
    MessageQueue<MensajeEquipaje>::create( IPC_BASE_FILE, MQ_VERIFICADO );
    MessageQueue<int>::create( IPC_BASE_FILE, MQ_NOTIFICACIONES );
    Sequence::create( IPC_BASE_FILE, SEQ_ID_PASAJERO );
    Sequence::create( IPC_BASE_FILE, SEQ_ID_EST_VERIF );
    Sequence::create( IPC_BASE_FILE, SEQ_ID_ROBOT );

    // Lanzo los distintos procesos

    std::string eVerificacionPath = "./estacionVerificacion";
    std::string eSospechososPath  = "./estacionSospechosos";
    std::string notificadorPath   = "./notificador";
    std::string robotPath         = "./robot";
    std::string pasajeroPath      = "./pasajero";

    /**/
    Argv args;
    args.pushArg( nVuelos );

    CPrinter::printOut( "Lanzando Estaciones de Verificacion.." );
    ProcessAux::launchProcess2( eVerificacionPath, nEstacionesVerificacion );

    CPrinter::printOut( "Lanzando Estacion de Sospechosos.." );
    ProcessAux::launchProcess2( eSospechososPath, 1, args );

    CPrinter::printOut( "Lanzando Robots.." );
    ProcessAux::launchProcess2( robotPath, nVuelos );

    CPrinter::printOut( "Lanzando Notificador.." );
    ProcessAux::launchProcess2( notificadorPath, 1, args );

    std::cout << "Lanzando pasajeros..." << std::endl;
    ProcessAux::launchProcess2( pasajeroPath, nPasajeros, args );
    /**/

    return 0;
}
